package upm.pb4agent.team3;

import jade.content.lang.Codec;
import jade.content.lang.sl.SLCodec;
import jade.content.onto.Ontology;
import jade.core.AID;
import jade.core.Agent;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.MessageTemplate;

import java.util.List;

import upm.pb4agent.ontology.PB4AgentOntology;

/**
 * This agent has the following functionality: 
 * <ul>
 * <li> 
 * <li> 
 * </ul>
 * @author Team3, UPM
 */
public final class MyAgent extends Agent{

	private static final long serialVersionUID = -4701995969726943676L;
	private static final Codec codec = new SLCodec();
	private static final Ontology ontology = PB4AgentOntology.getInstance();
	private static MyAgent myAgent = null;
	
	protected void setup(){
	    
    }
	
	public static MyAgent getInstance(){  
	       try{    	   
	    	   if(myAgent == null){
	    		   myAgent = new MyAgent();
				}
	    	   return myAgent;
		   }catch(Exception e){  
		     System.out.println("MyAgent: " + e.toString() );
		     return null;
	       }  
	} 
	
	
	public static boolean registerAgentInDF(Agent agent, String type){			
		try {
			DFAgentDescription dfd = new DFAgentDescription();
			ServiceDescription sd = new ServiceDescription();
			sd.setName(agent.getName());
			sd.setType(type);
			dfd.addServices(sd);
			DFService.register(agent, dfd);
			return true;
		} catch (FIPAException e) {
			System.out.println(Constant.NAME_MY_AGENT + ", error: "+ e.toString());
			return false;
		}

	}
	
	public static AID searchAgentInDF(Agent agent, String nameDf){
		try{
			AID aid = null;
			DFAgentDescription agDfd = new DFAgentDescription();
			ServiceDescription sd = new ServiceDescription();
			sd.setType(nameDf);
			agDfd.addServices(sd);

			//It finds agents of the required type
			DFAgentDescription[] registrationAgentDescriptionArray = new DFAgentDescription[1];
			registrationAgentDescriptionArray = DFService.search(agent, agDfd);
			
			if(registrationAgentDescriptionArray.length == 1){
				aid = (AID)registrationAgentDescriptionArray[0].getName();
			}
			return aid;
		}catch(FIPAException e){
			System.out.println(Constant.NAME_MY_AGENT + ", error: "+ e.toString());
			return null;
		}
	}
	
	public static MessageTemplate addMessageTemplateAND(List<Integer> performativeList, List<String> protocolList){		
		try{
			MessageTemplate mt = MessageTemplate.and(  MessageTemplate.MatchLanguage(codec.getName())
													  ,MessageTemplate.MatchOntology(ontology.getName())
										             );
			if(performativeList != null){
				for(int i=0; i<performativeList.size(); i++){
					mt = MessageTemplate.and(mt, MessageTemplate.MatchPerformative(performativeList.get(i).intValue()));
				}
			}
			if(protocolList != null){
				for(int i=0; i<protocolList.size(); i++){
					mt = MessageTemplate.and(mt, MessageTemplate.MatchProtocol(protocolList.get(i)));
				}
			}
			
			return mt;
		}catch(Exception e){
			System.out.println(Constant.NAME_MY_AGENT + ".addMessageTemplateAND(), error: "+ e.toString());
			return null;
		}
	}
	
	public static MessageTemplate addMessageTemplatOR(List<Integer> performativeList, List<String> protocolList){		
		try{
			MessageTemplate mt = MessageTemplate.and(  MessageTemplate.MatchLanguage(codec.getName())
													  ,MessageTemplate.MatchOntology(ontology.getName())
										             );
			
			if(performativeList != null){
				MessageTemplate mtOrPerformative = MessageTemplate.MatchPerformative(performativeList.get(0).intValue());
				for(int i=1; i<performativeList.size(); i++){
					mtOrPerformative = MessageTemplate.or(mtOrPerformative, MessageTemplate.MatchPerformative(performativeList.get(i).intValue()));
				}
				mt = MessageTemplate.and(mt, mtOrPerformative);
			}
			if(protocolList != null){
				MessageTemplate mtOrProtocol =  MessageTemplate.MatchProtocol(protocolList.get(0));			
				for(int i=1; i<protocolList.size(); i++){
					mtOrProtocol = MessageTemplate.or(mtOrProtocol, MessageTemplate.MatchProtocol(protocolList.get(i)));
				}
				mt = MessageTemplate.and(mt, mtOrProtocol);
			}					
			
			return mt;
		}catch(Exception e){
			System.out.println(Constant.NAME_MY_AGENT + ".addMessageTemplatOR() , error: "+ e.toString());
			return null;
		}
	}
	
	public static MessageTemplate addMessageTemplatOROR(List<Integer> performativeList, List<String> protocolList){		
		try{
			MessageTemplate mt = MessageTemplate.and(  MessageTemplate.MatchLanguage(codec.getName())
													  ,MessageTemplate.MatchOntology(ontology.getName())
										             );
			
			if(performativeList != null){
				MessageTemplate mtOrPerformative = MessageTemplate.MatchPerformative(performativeList.get(0).intValue());
				for(int i=1; i<performativeList.size(); i++){
					mtOrPerformative = MessageTemplate.or(mtOrPerformative, MessageTemplate.MatchPerformative(performativeList.get(i).intValue()));
				}
				mt = MessageTemplate.and(mt, mtOrPerformative);
			}
			if(protocolList != null){
				MessageTemplate mtOrProtocol =  MessageTemplate.MatchProtocol(protocolList.get(0));			
				for(int i=1; i<protocolList.size(); i++){
					mtOrProtocol = MessageTemplate.or(mtOrProtocol, MessageTemplate.MatchProtocol(protocolList.get(i)));
				}
				mt = MessageTemplate.or(mt, mtOrProtocol);
			}					
			
			return mt;
		}catch(Exception e){
			System.out.println(Constant.NAME_MY_AGENT + ".addMessageTemplatOR() , error: "+ e.toString());
			return null;
		}
	}
}